package cn.redragon.soa.common.exception;


import cn.redragon.soa.common.util.JsonUtil;
import lombok.Getter;
import lombok.ToString;

/**
 * The Class BaseException.
 */
@Getter
@ToString(onlyExplicitlyIncluded=true)
public abstract class BaseException extends RuntimeException implements CodeableException {

    /**
     * The Constant serialVersionUID.
     */
    private static final long serialVersionUID = -2416491642235544882L;

    /**
     * The code.
     */
    @ToString.Include
    private final String code;

    /**
     * The data.
     */
    private final Object data;

    /**
     * Instantiates a new demo base exception.
     *
     * @param code    the code
     * @param message the message
     */
    protected BaseException(String code, String message) {
        super(message);
        this.code = code;
        data = null;
    }

    /**
     * Instantiates a new demo base exception.
     *
     * @param code    the code
     * @param message the message
     */
    protected BaseException(String code, String message, Object data) {
        super(message);
        this.code = code;
        this.data = data;
    }

    /**
     * Instantiates a new demo base exception.
     *
     * @param message the message
     * @param e       the e
     */
    protected BaseException(String code, String message, Throwable e) {
        super(message, e);
        this.code = code;
        data = null;
    }

    /**
     * Instantiates a new demo base exception.
     *
     * @param message the message
     * @param e       the e
     */
    protected BaseException(String code, String message, Throwable e, Object data) {
        super(message, e);
        this.code = code;
        this.data = data;
    }

    /**
     * Instantiates a new base exception.
     *
     * @param error  the error
     * @param params the params
     */
    protected BaseException(BaseError error, Object... params) {
        this(error.getCode(), error.withParams(params));
    }

    /**
     * Instantiates a new base exception.
     *
     * @param error  the error
     * @param params the params
     */
    protected BaseException(Object data, BaseError error, Object... params) {
        this(error.getCode(), error.withParams(params), data);
    }

    /**
     * print formatted data
     *
     * @return
     */
    @ToString.Include
    private String data() {
        return data != null ? JsonUtil.objectToJsonStr(data) : null;
    }

    /**
     * print message as well
     *
     * @return
     */
    @ToString.Include
    public String message() {
        return this.getMessage();
    }
}
